package com.hziee.cosmanage.search.service.impl;

import com.alibaba.fastjson.JSON;
import com.hziee.cosmanage.search.config.ESConfig;
import com.hziee.cosmanage.search.constant.COSConstant;
import com.hziee.cosmanage.search.service.SearchService;
import com.hziee.cosmanage.search.vo.InviteVo;
import com.hziee.cosmanage.search.vo.SearchParam;
import com.hziee.cosmanage.search.vo.SearchResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.ibatis.ognl.EnumerationIterator;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class SearchServiceImpl implements SearchService {

    @Autowired(required = false)
    RestHighLevelClient client;

    @Override
    public SearchResult search(SearchParam searchParam) throws IOException {

        SearchResult searchResult = null;

        //1.准备检索请求
        SearchRequest searchRequest = buildSearchRequest(searchParam);


        //2.执行检索请求
        SearchResponse search = client.search(searchRequest, ESConfig.COMMON_OPTIONS);
        System.out.println(search);
        //3.分析响应数据
        searchResult = buildSearchResult(search,searchParam);
        return searchResult;
    }


    /**
     * 构建结果数据
     *
     * @param search
     * @return
     */
    private SearchResult buildSearchResult(SearchResponse search,SearchParam searchParam) {
        SearchResult searchResult = new SearchResult();
        List<InviteVo> list = new ArrayList<>();
        SearchHits hits = search.getHits();
        log.info("这是ES查询出来的数据："+search);
        if (hits != null && hits.getHits().length>0){
            for (SearchHit hit : hits) {
                //获取ES中数据的ID
                String id = hit.getId();
                String sourceAsString = hit.getSourceAsString();
                InviteVo inviteVo = JSON.parseObject(sourceAsString, InviteVo.class);
                inviteVo.setEsId(Integer.parseInt(id));
                list.add(inviteVo);
            }
        }
        searchResult.setInviteVos(list);
        searchResult.setPageNum(searchParam.getPageNum());
        //6.分页信息-总记录数
        Integer total = Math.toIntExact(hits.getTotalHits().value);
        searchResult.setTotal(total);
        //7.分页信息-总页码-计算
        int totalpages = (int)total%COSConstant.INVITE_PAGESIZE==0?(int)total/COSConstant.INVITE_PAGESIZE:(int)total/COSConstant.INVITE_PAGESIZE+1;
        searchResult.setTotalPages(totalpages);
        return searchResult;
    }

    /**
     * 准备请求
     *
     * @return
     */
    private SearchRequest buildSearchRequest(SearchParam searchParam) {
        SearchSourceBuilder builder = new SearchSourceBuilder();//构建DSL语句
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();

        //查询,模糊匹配
        if (!StringUtils.isEmpty(searchParam.getKeyword())) {
            boolQuery.must(QueryBuilders.matchQuery("job", searchParam.getKeyword()));
        }
        if (!StringUtils.isEmpty(searchParam.getCompany())) {
            boolQuery.must(QueryBuilders.matchQuery("company", searchParam.getCompany()));
        }
        if (searchParam.getCompany()==null&&searchParam.getKeyword()==null){
            boolQuery.must(QueryBuilders.matchAllQuery());
        }
        //filter
        if (searchParam.getCompanyId() != null) {
            boolQuery.filter(QueryBuilders.termQuery("companyId", searchParam.getCompanyId()));
        }
        //按照标签条件
        if (searchParam.getLabel().size() > 0 && searchParam.getLabel() != null) {
            List<String> label = searchParam.getLabel();
            label.stream().forEach(lab -> {
                boolQuery.filter(QueryBuilders.termQuery("label", lab));
            });
        }
        //按照价格区间
        if (!StringUtils.isEmpty(searchParam.getPay())) {
            //1_500/500_/_500
            RangeQueryBuilder range = QueryBuilders.rangeQuery("pay");
            String[] s = searchParam.getPay().split("_");
            if (s.length == 2) {
                range.gte(s[0]).lte(s[1]);
            } else if (s.length == 1) {
                if (searchParam.getPay().startsWith("_")) {
                    range.lte(s[0]);
                }

                if (searchParam.getPay().endsWith("_")) {
                    range.gte(s[0]);
                }
            }
            boolQuery.filter(range);
        }
        builder.from((searchParam.getPageNum() - 1) * COSConstant.INVITE_PAGESIZE);
        builder.size(COSConstant.INVITE_PAGESIZE);
        builder.query(boolQuery);
        System.out.println("构建的DSL语句：" + builder.toString());
        SearchRequest searchRequest = new SearchRequest(new String[]{COSConstant.INVITE_INDEX}, builder);
        return searchRequest;
    }


}
